<?php
declare(strict_types=1);

namespace App\Service;

use App\Model\Dao\BankInfoLogDao;
use App\Model\Enum\BankTypeEnum;
use App\Utils\CustomUtils;
use App\Utils\StringUtils;
use Hyperf\Database\Query\Builder;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use App\Model\Dao\BankInfoDao;
use App\Exception\XZXValidationException;
use App\Constants\XZXResponseCode;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Utils\Coroutine;
use App\Utils\DateUtils;
use Hyperf\Utils\Arr;

class BankInfoService {

    /**
     * @Inject()
     * @var BankInfoDao
     */
    private $BankInfoDao;

    /**
     * @Inject()
     * @var BankInfoLogDao
     */
    private $BankInfoLogDao;

    /**
     * 列表
     *
     * @param array $param
     *
     * @return array
     */
    public function list (array $param) {

        $limit = $param['limit'];
        $page  = $param['page'];

        $total = $this->BankInfoDao->getCount($param);
        $list  = $this->BankInfoDao->getList($param, $page, $limit);

        foreach ($list as $k => $v) {
            $v['createTime'] = DateUtils::getDateTime($v['createTime']);
            $list[$k]        = $v;
        }

        $data = [
            'total' => $total,
            'list'  => $list,
        ];

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 详情
     *
     * @param $param
     *
     * @return array
     */
    public function get ($param) {

        $result = $this->BankInfoDao->get($param['id']);

        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $result);
    }

    /**
     * 从参数过滤得到添加/更新数组
     *
     * @param $param
     *
     * @return array
     */
    protected function _filterUpdate ($param) {

        $update = Arr::only($param, [
            'bankName',
            // 'bankNo',
            'type',
            'host',
            'port',
            'isProxy',
            'proxyHost',
            'proxyPort',
            'status',
        ]);

        return $update;
    }

    /**
     * 添加
     *
     * @param $param
     *
     * @return array
     * @throws \Throwable
     */
    public function add ($param) {

        $update = $this->_filterUpdate($param);
        $update = array_merge($update, Arr::only($param, ['createBy', 'updateBy']));

        $update['id'] = StringUtils::uuidV4();

        // 生成银行编号
        $last = $this->BankInfoDao->getLast();
        if (empty($last)) {
            $param['bankNo'] = '1000';
        }
        else {
            $lastMchNo        = $last['bankNo'];
            $lastMchNo        = intval($lastMchNo);
            $update['bankNo'] = $lastMchNo + 1;
        }

        Db::beginTransaction();

        try {

            $this->BankInfoDao->insert($update);

            $this->_addLog($update['id']);

        } catch (\Throwable $e) {

            Db::rollBack();

            throw $e;
        }

        Db::commit();


        $data = ['id' => $update['id']];

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), $data);
    }

    /**
     * 编辑
     *
     * @param $param
     *
     * @return array
     */
    public function edit ($param) {

        $id = Arr::pull($param, 'id');

        $info = $this->BankInfoDao->get($id);
        if (!$info) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $update = $this->_filterUpdate($param);
        $update = array_merge($update, Arr::only($param, ['updateBy']));

        Db::beginTransaction();

        try {

            $this->BankInfoDao->update($id, $update);

            $this->_addLog($id);

        } catch (\Throwable $e) {
            Db::rollBack();
            throw $e;
        }

        Db::commit();


        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }

    /**
     * 删除
     *
     * @param $param
     *
     * @return array
     */
    public function del ($param) {

        $result = $this->BankInfoDao->get($param['id']);

        if (!$result) {
            throw new XZXValidationException(XZXResponseCode::getMessage(XZXResponseCode::DATA_NOT_FOUND));
        }

        $this->BankInfoDao->del($param['id'], false);

        return CustomUtils::xeServiceReturnData(XZXResponseCode::SUCCESS_CODE, XZXResponseCode::getMessage(XZXResponseCode::SUCCESS_CODE), CustomUtils::xzxEmptyObject());
    }


    public function options ($param) {

        $list = $this->BankInfoDao->getWhereList(function (Builder $q) use ($param) {
            if (!empty($param['search'])) {
                $q->where('bankName', 'like', "%{$param["search"]}%");
            }
            $q->where('status', 1);
        });

        $list = array_map(function ($item) {
            return [
                'value' => $item['id'],
                'label' => $item['bankName'],
            ];
        }, $list);

        $data = $list;

        return CustomUtils::buildSuccess($data);
    }

    public function typeOptions ($param) {

        $list = BankTypeEnum::born()->getOptions();

        $data = $list;

        return CustomUtils::buildSuccess($data);
    }

    public function paramOptions ($param) {

        $id = $param['id'];

        $info = $this->BankInfoDao->get($id);

        if (!$info) {
            throw new \Exception("找不到该银行");
        }

        $config = config('bank.bankParam', []);

        $bankParam = isset($config[$info['type']]) ? $config[$info['type']] : [];

        $data = $bankParam;

        return CustomUtils::buildSuccess($data);

    }

    protected function _addLog ($id) {

        $info = $this->BankInfoDao->get($id);

        $update           = $info;
        $update['id']     = StringUtils::uuidV4();
        $update['bankId'] = $info['id'];

        unset($update['createTime']);
        unset($update['updateTime']);

        $this->BankInfoLogDao->insert($update);
    }

    public function getInfoLog ($param) {

        $page  = Arr::pull($param, 'page');
        $limit = Arr::pull($param, 'limit');

        $total = $this->BankInfoLogDao->getCount($param);
        $list  = $this->BankInfoLogDao->getList($param, $page, $limit);

        $data = [
            'total' => $total,
            'list'  => $list,
        ];

        return CustomUtils::buildSuccess($data);
    }

}
